package com.example.gulimall.search.thread;


import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class ThreadTest {

    // 开启线程池
    public static ExecutorService executorService = Executors.newFixedThreadPool(10);


    public static void main(String[] args) throws ExecutionException, InterruptedException {

        // runAsync启动异步任务
        CompletableFuture.runAsync(()->{
            System.out.println("当前线程");
            int i = 10/2;
            System.out.println("运行结果"+i);
        },executorService);

        // 异步任务的链式执行 (在同一个线程)
        CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
            System.out.println("当前线程");
            int i = 10 / 2;
            System.out.println("运行结果" + i);
            return i;
        }, executorService).whenComplete((res,exception)->{
            // 如果这里用AyscWhenComplete表示开启一个新线程去做后面的任务
            // 感知异常罢了
            System.out.println("结果是"+res+"异常是"+exception);
        }).exceptionally(throwable -> {
            // 指定发生异常返回什么值
            return 10;
        });
        System.out.println(future.get());

        //handle也可以处理 方法执行完成后的处理
        CompletableFuture<Integer> futures = CompletableFuture.supplyAsync(() -> {
            System.out.println("当前线程");
            int i = 10 / 2;
            System.out.println("运行结果" + i);
            return i;
        }, executorService).handle((res,exception)->{
            if(res != null)
                return res*2;
            else
                return 0;
        });

        //线程串行化
        // 1.thenApply 获取上一个任务返回结果，返回当前结果
        // 2.thenAccept 消费处理结果，无返回结果
        // 3.thenRun 只要上面的任务执行完成 就执行thenRun 只是处理完任务后 执行thenRun的后续操作
        // 两个任务有先后关系但是没有参数传递
        // 带有async默认都是异步执行的
        CompletableFuture.supplyAsync(() -> {
            System.out.println("当前线程");
            int i = 10 / 2;
            System.out.println("运行结果" + i);
            return i;
        }, executorService).thenRunAsync(()->{
            System.out.println("任务2");
        });


        /*
        两任务合并：两个任务都必须完成，出发该任务
        thenCombine: 组合两个future，获取两个future的返回结果，返回当前任务的返回值
        thenAcceptBoth：组合两个future，获取两个的返回结果，没有返回值
        runAfterBoth：不组合结果，完成后就返回
         */

        //组合future和futures
        future.runAfterBothAsync(futures,()->{
            System.out.println("两个任务都完成了！");
        },executorService);

        /*
        两任务选一：两个任务有一个就行
        ApplyToEither: 一个future，获取两个future的返回结果，返回当前任务的返回值
        AcceptEither：一个future的返回结果，没有返回值
        runAfterEither：不组合结果，完成后就返回
         */
        future.runAfterEitherAsync(futures,()->{
            System.out.println("两个任务都完成了！");
        },executorService);

        //多任务组合
        // allof 全部完成
        // anyof 有一个完成就好
        CompletableFuture<String> a = CompletableFuture.supplyAsync(() -> {
            System.out.println("线程1");
            return "1";
        });

        CompletableFuture<String> b = CompletableFuture.supplyAsync(() -> {
            System.out.println("线程1");
            return "2";
        });

        CompletableFuture<String> c = CompletableFuture.supplyAsync(() -> {
            System.out.println("线程1");
            return "3";
        });


        CompletableFuture.allOf(a,b,c);

    }


}
